package com.lhh.myspringboot.java8;

import com.lhh.myspringboot.bean.Student;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

/**
 * 流的中间操作
 */
public class StreamMiddleOpreter {
    public static void main(String[] args) {


        /*
        1 筛选与切片

        filter()：过滤流中的某些元素
        limit(n)：获取n个元素
        skip(n)：跳过n元素，配合limit(n)可实现分页
        distinct()：通过流中元素的 hashCode() 和 equals() 去除重复元素
         */
        Stream<Integer> stream = Stream.of(6, 4, 6, 7, 3, 9, 8, 10, 12, 14, 14);

        Stream<Integer> newStream = stream.filter(s -> s > 5) //6 6 7 9 8 10 12 14 14
                .distinct() //6 7 9 8 10 12 14
                .skip(2) //9 8 10 12 14
                .limit(2); //9 8
        newStream.forEach(System.out::println);

        /*
        2 映射

        map：接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        flatMap：接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
         */

        List<String> list = Arrays.asList("a,b,c", "1,2,3");

            //将每个元素转成一个新的且不带逗号的元素
        Stream<String> s1 = list.stream().map(s -> s.replaceAll(",", ""));
        s1.forEach(System.out::println); // abc  123

        Stream<String> s3 = list.stream().flatMap(s -> {
            //将每个元素转换成一个stream
            String[] split = s.split(",");
            Stream<String> s2 = Arrays.stream(split);
            return s2;
        });
        s3.forEach(System.out::println); // a b c 1 2 3

        /*
        3 排序

        sorted()：自然排序，流中元素需实现Comparable接口
        sorted(Comparator com)：定制排序，自定义Comparator排序器
         */

        List<String> list2 = Arrays.asList("aa", "ff", "dd");
        //String 类自身已实现Compareable接口
        list2.stream().sorted().forEach(System.out::println);// aa dd ff

        Student ss1 = new Student(10,1,"aa");
        Student ss2 = new Student(20,1,"bb");
        Student ss3 = new Student(30,1,"aa");
        Student ss4 = new Student( 40,1,"dd");
        List<Student> studentList = Arrays.asList(ss1, ss2, ss3, ss4);

        //自定义排序：先按姓名升序，姓名相同则按年龄升序
        studentList.stream().sorted(
                (o1, o2) -> {
                    if (o1.getName().equals(o2.getName())) {
                        return o1.getAge() - o2.getAge();
                    } else {
                        return o1.getName().compareTo(o2.getName());
                    }
                }
        ).forEach(System.out::println);

        // 或者这种写法
        studentList.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));
        studentList.forEach(System.out::println);


        /*
        4 消费

        peek：如同于map，能得到流中的每一个元素。但map接收的是一个Function表达式，有返回值；
        而peek接收的是Consumer表达式，没有返回值。
         */


        Student sss1 = new Student( 10,1,"aa");
        Student sss2 = new Student( 20,1,"bb");
        List<Student> studentList4 = Arrays.asList(sss1, sss2);

        studentList4.stream()
                .peek(o -> o.setAge(100))
                .forEach(System.out::println);


        /*
         结果：
        Student{age=100, name='aa'}
        Student{age=100, name='bb'}
         */



    }
}
